/*
 * Copyright (c) Huawei Device Co., Ltd. 2023. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef SE_SERVICE_MANAGER_H
#define SE_SERVICE_MANAGER_H

#include <vector>
#include "common_utils.h"
#include "iremote_object.h"
#include "iservice_registry.h"
#include "nocopyable.h"
#include "singleton.h"
#include "system_ability.h"
#include "service_impl.h"
#include "secure_element_agent.h"

namespace OHOS {
namespace SE {
class SecureElementAgent;
class ServiceImpl;
using SeNameAndAgentMap = std::pair<std::string, std::shared_ptr<SecureElementAgent>>;
using SeAgentList = std::vector<SeNameAndAgentMap>;

/**
 * @brief define the SA service running state.
 */
enum class ServiceRunningState {
    // SA is stop
    STATE_NOT_START = 0,

    // SA is running.
    STATE_RUNNING
};

class ServiceManager final : public SystemAbility,
                             public std::enable_shared_from_this<ServiceManager> {
    DECLARE_DELAYED_SINGLETON(ServiceManager)
    DECLARE_SYSTEM_ABILITY(ServiceManager);

public:
    DISALLOW_COPY_AND_MOVE(ServiceManager);

    void OnStart() override;
    void OnStop() override;

private:
    /**
     * @brief Found and init all secure element, add all agents based on the secure element found; called by OnStart.
     */
    bool Init();

    /**
     * @brief Found the secure element and add it into SeAgentList.
     */
    void AddSecureElementAgent();
#ifdef DYNAMIC_LOAD_SE_HOST
    /**
     * @brief load secure element host.
     */
    bool LoadSecureElementHost();

    /**
     * @brief unload secure element host.
     */
    bool UnLoadSecureElementHost();
#endif
private:
    // the sa is init success or not.
    bool registerToService_ = false;

    // the service running state.
    ServiceRunningState runningState_{ServiceRunningState::STATE_NOT_START};

    // ServiceImpl instance used to access the public functions.
    sptr<ServiceImpl> serviceImpl_ {};

    // all secure elements found, the list used to manager all secure elements.
    SeAgentList secureElementAgents_{};

    // for event log
    std::string eventLog_ {};

#ifdef DYNAMIC_LOAD_SE_HOST
    // the service_element_host running state.
    bool secureElementHostState_ = false;
#endif

    friend class ServiceImpl;
    friend class ReaderImpl;
    friend class SessionImpl;
    friend class SecureElementAgent;
};
}  // namespace SE
}  // namespace OHOS
#endif // SE_SERVICE_MANAGER_H
